package im

import (
	"fmt"
	"net"
	"strings"
)

type User struct {
	Name    string
	Addr    string
	Channel chan string
	conn    net.Conn
	server  *Server
}

func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:    userAddr,
		Addr:    userAddr,
		Channel: make(chan string),
		conn:    conn,
		server:  server,
	}
	// 启动监听当前user channel消息的goroutine
	go user.ListenMessage()

	return user
}

// Online 用户上线
func (this *User) Online() {
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()
	this.server.Broadcast(this, "上线")
}

// Offline 用户下线
func (this *User) Offline() {
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()
	this.server.Broadcast(this, "下线")
}

// ListenMessage 监听当前User channel的方法，有消息就发给客户端
func (this *User) ListenMessage() {
	for {
		msg := <-this.Channel
		this.SendMessage(msg + "\n")
	}
}

// SendMessage 给当前用户的客户端发送消息
func (this *User) SendMessage(msg string) {
	_, err := this.conn.Write([]byte(msg))
	if err != nil {
		fmt.Println("Send Message ERROR:", err)
		return
	}
}

func (this *User) HandleMessage(msg string) {
	if msg == "who" {
		this.GetOnlineUsers()
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		this.Rename(msg[7:])
	} else if len(msg) > 3 && msg[:3] == "to|" {
		this.PrivateChat(msg[3:])
	} else {
		this.server.Broadcast(this, msg)
	}
}

// GetOnlineUsers 获取在线用户
func (this *User) GetOnlineUsers() {
	this.server.mapLock.Lock()
	for _, user := range this.server.OnlineMap {
		this.Channel <- "[" + user.Addr + "]" + user.Name + ": online..\n"
	}
	this.server.mapLock.Unlock()
}

func (this *User) Rename(newName string) {
	_, ok := this.server.OnlineMap[newName]
	if ok {
		this.SendMessage("【" + newName + "】已经被占用\n")
		return
	}

	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.OnlineMap[newName] = this
	this.server.mapLock.Unlock()
	this.Name = newName
	this.SendMessage("修改成功，当前用户名：" + newName + "\n")
}

func (this *User) PrivateChat(str string) {
	msgs := strings.Split(str, "|")
	toUserName := msgs[0]
	msg := msgs[1]

	// 数据校验
	if toUserName == "" {
		this.SendMessage("消息格式不正确，请使用\"to|张三|消息\"的格式\n")
		return
	}
	if msg == "" {
		this.SendMessage("消息不能为空\n")
		return
	}
	toUser, ok := this.server.OnlineMap[toUserName]
	if !ok {
		this.SendMessage("用户不存在！\n")
		return
	}

	toUser.SendMessage(msg)
}
